<?php
/**
 * @category modules
 * @package  mail
 * @subpackage mail/api
 */

/**
 * <code>
 * Nuo::getApi('mail')
 * result: Mail_Api_Mail instance
 * </code>
 * @name Mail_Api_Mail
 * @version 1.0
 * @author  Nam nguyen <nam.ngvan@gmail.com>
 * @since   Apr 17, 2013
 */
class Mail_Api_Mail
{

	/**
	 * Default mail plugin will be used.
	 *
	 * @static
	 * @var string
	 */
	CONST DEFAULT_MAIL_PLUGIN = 'mail/mail/simple';
	
	/**
	 * Fetch mailer instance.
	 * @access  public
	 * @param   array   $data
	 * @param   array   $config
	 * @return  bool
	 */
	function sendMail($data, $config = NULL)
	{
		if (!isset($data['to_address']) or empty($data['to_address']))
		{
			throw new Exception('param "to_address" is required!');
		}

		if (NULL == $config)
		{
			$config = Nuo::getConfig('mail/config');
		}

		require_once LEGACY_DIR . 'phpmailer/class.phpmailer.php';

		$debug = isset($config['debug']) ? $config['debug'] : 1;

		/**
		 * @var PHPMailer
		 */
		$mailer = new PHPMailer();
		//$mailer -> Debugoutput = 'error_log';

		if ($config['adapter'] == 'smtp')
		{
			//$mailer -> SMTPDebug = $debug;
			$mailer -> IsSMTP();

			$mailer -> Host = $config['smtp_host'];
			$mailer -> Port = $config['smtp_port'];

			if ($config['smtp_auth'])
			{
				$mailer -> SMTPAuth = 1;
				$mailer -> Username = $config['smtp_username'];
				$mailer -> Password = $config['smtp_password'];
			}

			if (in_array($config['smtp_secure'], array(
				'ssl',
				'tls'
			)))
			{

				$mailer -> SMTPSecure = $config['smtp_secure'];
			}

		}
		else
		{
			$mailer -> IsMail();
		}

		if (!isset($data['from_address']) or empty($data['from_address']))
		{
			$data['from_address'] = $config['from_address'];
		}

		if (!isset($data['from_name']) or empty($data['from_name']))
		{
			$data['from_name'] = $config['from_name'];
		}

		if (!isset($data['reply_address']) or empty($data['reply_address']))
		{
			$data['reply_address'] = $config['reply_address'];
		}

		if (!isset($data['reply_name']) or empty($data['reply_name']))
		{
			$data['reply_name'] = $config['reply_name'];
		}

		if (!isset($data['to_name']))
		{
			$data['to_name'] = '';
		}

		$mailer -> SetFrom($data['from_address'], $data['from_name']);

		$mailer -> AddReplyTo($data['reply_address'], $data['reply_name']);

		$mailer -> Subject = $data['subject'];

		$mailer -> MsgHTML($data['body_html']);

		$mailer -> AltBody = $data['body_text'];

		/**
		 * configure email to send
		 */
		$mailer -> addAddress($data['to_address'], $data['to_name']);

		/**
		 * Send mailer
		 */
		$result = $mailer -> send();

		return (bool)$result;
	}

	/**
	 * @access  public
	 * @param   string   $key
	 * @param   string   $to    accept, email address, user_id or array{name, address}
	 * @param   array    $params
	 * @param   bool     $now   send immediatel, DEFAULT false
	 * @return  bool
	 */
	public function send($key, $to, $params = array(), $now = TRUE)
	{

		$data = $this -> compile($key, $to, $params);
		$data['to_address'] = $to;

		// send immediately
		if (!$now)
		{
			/**
			 * Add mail item to queue table
			 */
			Nuo::getTable('core/mail/queue') -> addItem($data);
		}
		else
		{
			/**
			 * Send mail directly
			 */
			return self::sendMail($data);
		}

		return TRUE;
	}

	/**
	 * Compile to mail array data.
	 * <code>
	 * Nuo::getApi('mail')->compile('user.signup_welcome', 'nam.ngvan@gmail.com', array('code'=>123))
	 *
	 * Result:  array(
	 * 		 'subject' => 'test subject',
	 * 		 'body_text' => 'test body test',
	 * 		 'body_html' => 'test body html',
	 * 		 'extra' => array('conbo' => 'what the help'),
	 * 		 'from_address' => 'test from address',
	 * 		 'from_name' => 'test from name',
	 * 		 'to_name' => 'test from name',
	 * 		 'to_address' => 'test from name',
	 * 		 'use_queue' => 1,
	 * 	 );
	 * </code>
	 * @access  public
	 * @param   string $key
	 * @param   string $to
	 * @param   array  $data
	 * @return  array $data
	 * @throws  Exception
	 */
	public function compile($key, $to, $params)
	{

		$tpl = $this -> getTemplate($key);

		if (!$tpl)
		{
			throw new Exception(strtr('Unable to load mail template "$key"', array('$key' => $key)));
		}

		$plugin = $tpl['plugin'];

		/**
		 * check to load default plugin
		 */
		if (!$plugin)
		{
			$plugin = self::DEFAULT_MAIL_PLUGIN;
		}

		$executer = Nuo::getPlugin($plugin);

		if (!$executer or !$executer instanceof Nuo_Plugin_Mail_Abstract)
		{
			throw new Exception("Plugin $plugin does not exists or not instance of Nuo_Plugin_Mail_Abstract");
		}

		/**
		 * set params
		 */
		return $executer -> execute($tpl, $to, $params);
	}

	/**
	 * Get mail template array data
	 * <code>
	 * Nuo::getApi('mail')->getTemplate('user.signup_welcome')
	 * Result: array(
	 *  template_id=>12,
	 *  subject =>'welcome subject',
	 *  ...
	 * )
	 * </code>
	 * @todo    use cached to cached mail template instead of fetch from database too many time.
	 * @access  public
	 * @param   string  $key  Template key
	 * @param   string  $lang Language Id
	 * @return  array
	 * @throws  Exception
	 */
	function getTemplate($key, $lang = NULL)
	{
		/**
		 * @var Mail_Table_Template
		 */
		$table = Nuo::getTable('core/mail');

		$select = $table -> select() -> where('template_key=?', $key);

		/**
		 * @var Mail_Table_Model_Template
		 */
		$tpl = $table -> fetchRow($select);

		if (!$tpl)
		{
			throw new Exception('Could not load mail template code ' . $key);
		}

		/**
		 * @var Mail_Table_Translation
		 */
		$table = Nuo::getTable('core/mail/translation');

		/**
		 * @var Mail_Table_Translation
		 */
		$trans = NULL;

		if (!$lang)
		{
			$lang = Intl::getLanguage();
		}

		if ($lang)
		{
			$select = $table -> select() -> where('template_id=?', $tpl -> getId());
			$select -> where('lang_id=?', $lang);
			$trans = $table -> fetchRow($select);
		}

		if (!$trans)
		{
			$select = $table -> select() -> where('template_id=?', $tpl -> getId());
			$trans = $table -> fetchRow($select);
		}

		if (!$trans)
		{
			throw new Exception('Could not fetch mail translation for template ' . $key);
		}

		$result = array_merge($tpl -> toArray(), $trans -> toArray());

		return $result;
	}

}
